package org.dsbackend.controller;

import org.dsbackend.entity.JsonData;
import org.dsbackend.entity.ResultException;
import org.dsbackend.model.Shop;
import org.dsbackend.repository.ShopRepository;
import org.dsbackend.util.CharUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

@RestController
@RequestMapping(value="/shops")
public class ShopController {
    @Autowired
    private ShopRepository shopRepository;

    @PreAuthorize("hasRole('SYSTEM_MANAGER')")
    @RequestMapping(value="/{id}", method=RequestMethod.GET)
    public JsonData getShop(@PathVariable Long id) {
        Shop shop;
        try{
            shop = shopRepository.findById(id).get();
        }
        catch (NoSuchElementException e) {
            throw new ResultException(401, "No shop found");
        }
        return new JsonData(0, "success", shop);
    }

    @RequestMapping(value="/", method=RequestMethod.GET)
    public JsonData getShopList() {
        List<Shop> shops;
        try {
            shops = shopRepository.findAll();
        }
            catch (Exception e) {
            throw new ResultException(402, e.toString());
        }
        Iterator<Shop> iter = shops.iterator();
        while (iter.hasNext()) {
            Shop temp = iter.next();
            if (temp.isShopAvailable() == false) iter.remove();
        }
        if (shops.isEmpty())
            throw new ResultException(401, "No shop found");

        return new JsonData(0, "success", shops);
    }

    @RequestMapping(value="/", method=RequestMethod.POST)
    public JsonData postShop(@RequestParam(name="shopName") String shopname,
                             @RequestParam(name="latitude") String latitudeStr,
                             @RequestParam(name="longitude") String longitudeStr) {
        double latitude, longitude;
        if (latitudeStr.equals("")) {
            throw new ResultException(401, "latitude is empty");
        }
        else {
            latitude = Double.parseDouble(latitudeStr);
            if (latitude < -90 || latitude > 90) {
                throw new ResultException(403, "illegal latitude");
            }
        }

        if (longitudeStr.equals("")) {
            throw new ResultException(403, "longitude is empty");
        }
        else {
            longitude = Double.parseDouble((longitudeStr));
            if (longitude < -180 || longitude > 180) {
                throw new ResultException(403, "illegal longitude");
            }
        }

        if (shopname.equals("")) {
            throw new ResultException(403, "shopName is empty");
        }
        else if (CharUtils.hasIllegalChar(shopname)) {
            throw new ResultException(403, "shopName contains illegal character");
        }
        else {
            Shop shop = new Shop(shopname, longitude, latitude);
            try {
                shopRepository.save(shop);
            }
            catch (DataIntegrityViolationException e) {
                throw new ResultException(403, "shopName must be unique");
            }
            return new JsonData(0, "success", null);
        }

    }



    @RequestMapping(value="/{id}", method=RequestMethod.PUT)
    public JsonData putShop(@PathVariable Long id,
                            @RequestParam(name="shopName", required=false) String shopname,
                            @RequestParam(name="latitude", required=false) String latitudeStr,
                            @RequestParam(name="longitude", required=false) String longitudeStr) {
        double latitude,longitude;
        try {
            Shop shop = shopRepository.findById(id).get();
            if (shopname != null) {
                if (!shopname.equals("")) {
                    if (CharUtils.hasIllegalChar(shopname)) {
                        throw new ResultException(403, "shopname contains illegal character");
                    }
                    else {
                        shop.setShopname(shopname);
                    }
                }
            }
            if (latitudeStr != null) {
                if (!latitudeStr.equals("")) {
                    latitude = Double.parseDouble(latitudeStr);
                    if (latitude < -90 || latitude > 90) {
                        throw new ResultException(403, "illegal latitude");
                    }
                    else {
                        shop.setLatitude(latitude);
                    }
                }
            }
            if (longitudeStr != null) {
                if (!longitudeStr.equals("")) {
                    longitude = Double.parseDouble(longitudeStr);
                    if (longitude < -180 || longitude > 180) {
                        throw new ResultException(403, "illegal longitude");
                    }
                    else {
                        shop.setLongitude(longitude);
                    }
                }
            }
            try {
                shopRepository.save(shop);
            }
            catch (Exception e) {
                throw new ResultException(402, e.toString());
            }
        }
        catch (NoSuchElementException e) {
            throw new ResultException(401, "No shop found");
        }
        return new JsonData(0, "success", null);
    }

    @RequestMapping(value="/{id}", method=RequestMethod.DELETE)
    public JsonData deleteShop(@PathVariable Long id) {
        Shop shop;
        try {
            shop = shopRepository.findById(id).get();
        }
        catch (NoSuchElementException e) {
            throw new ResultException(401, "No shop found");
        }
        shop.setShopAvailable(false);
        try {
            shopRepository.save(shop);
        }
        catch (Exception e) {
            throw new ResultException(402, e.toString());
        }
        return new JsonData(0, "success", null);
    }

}
